package com.iot.manager.utils;

import android.util.Log;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.concurrent.atomic.AtomicBoolean;

public class UdpManager {
    private static final String TAG = "UdpManager";
    private static final int DEVICE_PORT = 8266; // 设备UDP端口
    private static final int TIMEOUT = 5000; // 超时时间（毫秒）
    private static final int MAX_RETRIES = 3; // 最大重试次数

    private DatagramSocket socket;
    private final AtomicBoolean isRunning = new AtomicBoolean(false);
    private final Object lock = new Object();

    public interface UdpCallback {
        void onSuccess();
        void onError(String error);
    }

    public UdpManager() {
        initializeSocket();
    }

    private void initializeSocket() {
        synchronized (lock) {
            try {
                if (socket != null && !socket.isClosed()) {
                    socket.close();
                }
                socket = new DatagramSocket();
                socket.setSoTimeout(TIMEOUT);
                isRunning.set(true);
            } catch (SocketException e) {
                Log.e(TAG, "Error creating UDP socket", e);
                isRunning.set(false);
            }
        }
    }

    public void sendConfig(String configData, UdpCallback callback) {
        if (!isRunning.get()) {
            initializeSocket();
        }

        if (!isRunning.get() || socket == null) {
            callback.onError("UDP socket not initialized");
            return;
        }

        new Thread(() -> {
            int retryCount = 0;
            boolean success = false;

            while (retryCount < MAX_RETRIES && !success && isRunning.get()) {
                try {
                    synchronized (lock) {
                        if (socket == null || socket.isClosed()) {
                            initializeSocket();
                            if (!isRunning.get()) {
                                callback.onError("Failed to initialize UDP socket");
                                return;
                            }
                        }

                        // 发送配置数据到设备
                        byte[] sendData = configData.getBytes();
                        DatagramPacket sendPacket = new DatagramPacket(
                                sendData,
                                sendData.length,
                                InetAddress.getByName("192.168.4.1"), // 设备热点IP
                                DEVICE_PORT
                        );
                        socket.send(sendPacket);

                        // 等待设备响应
                        byte[] receiveData = new byte[1024];
                        DatagramPacket receivePacket = new DatagramPacket(
                                receiveData,
                                receiveData.length
                        );
                        socket.receive(receivePacket);

                        // 检查响应
                        String response = new String(
                                receivePacket.getData(),
                                0,
                                receivePacket.getLength()
                        );
                        if (response.equals("OK")) {
                            success = true;
                            callback.onSuccess();
                        } else {
                            retryCount++;
                            if (retryCount < MAX_RETRIES) {
                                Thread.sleep(1000); // 等待1秒后重试
                            }
                        }
                    }
                } catch (UnknownHostException e) {
                    Log.e(TAG, "Unknown host", e);
                    callback.onError("Unknown host: " + e.getMessage());
                    break;
                } catch (SocketTimeoutException e) {
                    Log.e(TAG, "Socket timeout", e);
                    retryCount++;
                    if (retryCount >= MAX_RETRIES) {
                        callback.onError("Connection timeout after " + MAX_RETRIES + " attempts");
                    }
                } catch (IOException e) {
                    Log.e(TAG, "IO error", e);
                    retryCount++;
                    if (retryCount >= MAX_RETRIES) {
                        callback.onError("IO error: " + e.getMessage());
                    }
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    callback.onError("Operation interrupted");
                    break;
                } catch (Exception e) {
                    Log.e(TAG, "Unexpected error", e);
                    callback.onError("Unexpected error: " + e.getMessage());
                    break;
                }
            }

            if (!success && retryCount >= MAX_RETRIES) {
                callback.onError("Failed to send config after " + MAX_RETRIES + " attempts");
            }
        }).start();
    }

    public void close() {
        synchronized (lock) {
            isRunning.set(false);
            if (socket != null && !socket.isClosed()) {
                try {
                    socket.close();
                } catch (Exception e) {
                    Log.e(TAG, "Error closing UDP socket", e);
                } finally {
                    socket = null;
                }
            }
        }
    }

    public boolean isRunning() {
        return isRunning.get() && socket != null && !socket.isClosed();
    }

    @Override
    protected void finalize() throws Throwable {
        close();
        super.finalize();
    }
} 